import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import {
  ACCESS_TOKEN_EXPIRATION_TIME,
  USER_ACCESS_TOKEN_KEY,
} from '../caches/constants';
import { MemoryService } from '../caches/memory.service';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(
    private readonly usersService: UsersService,
    private readonly jwtService: JwtService,
    private readonly memoryService: MemoryService,
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return this.generateToken(payload);
  }

  async logout(user: any) {
    if (user.userId) {
      await Promise.all([this.memoryService.del(this.getAccessTokenKey(user))]);
      return true;
    }
    return false;
  }

  generateToken(payload: any) {
    const access_token = this.jwtService.sign(payload);
    this.memoryService.set(
      this.getAccessTokenKey(payload),
      access_token,
      ACCESS_TOKEN_EXPIRATION_TIME,
    );
    return {
      access_token,
    };
  }

  getAccessTokenKey(payload: any) {
    return `${USER_ACCESS_TOKEN_KEY}:${payload.userId}`;
  }
}
